from rest_framework.response import Response
from rest_framework.views import APIView
from django_redis import get_redis_connection
from rest_framework import status
import base64, pickle

from .serializers_test1 import CartsCreateSerializer

class CartsView(APIView):
    """
    购物车视图
    """
    def perform_authentication(self, request):
        """
        重写此方法,用于进入此视图后再进行身份验证
        :param request:
        :return:
        """
        pass

    def post(self, request):
        """
        向购物车添加商品
        :param request:
        :return:
        """
        serializer = CartsCreateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        sku_id = serializer.validated_data.get("sku_id")
        count = serializer.validated_data.get("count")
        selected = serializer.validated_data.get("selected")


        try:
            user = request.user
        except:
            user = None
        # 判断是否登录
        if user is not None and user.is_authenticated:
            # 登录 保持在redis中
            redis_con = get_redis_connection("carts")
            pl = redis_con.pipeline()
            # redis 哈希表的操作,如果hincrby(key field value)如果key不存在,则创建,
            # 存在则执行,field不存在则创建,增量为0,存在则增加
            pl.hincrby("cart_%s" % user.id, sku_id, count)
            # 往set无序集合中添加,如果有则忽略
            pl.sadd("selected_%s" % user.id, sku_id)
            pl.execute()

            return Response(serializer.data, status=status.HTTP_201_CREATED)

        else:
            # 未登录
            cookie_str = request.COOKIES.get("cart")
            # 判断cookie中是否有购物车信息
            if cookie_str:
                # 转码
                cookie_str_types = cookie_str.encode()
                cookie_dict = base64.b64decode(cookie_str_types)
                cart_dict = pickle.loads(cookie_dict)

                if sku_id in cart_dict.keys():
                    origin_count = cart_dict[sku_id]["count"]
                    count += origin_count
                    cart_dict[sku_id]["count"] = count
                else:
                    cart_dict = {}

                cart_dict[sku_id] = {
                    "count": count,
                    "selected": selected,
                }

            else:
                cart_dict = {}

            cookie_dict = pickle.dumps(cart_dict)
            cookie_str_types = base64.b64encode(cookie_dict)
            cookie_str = cookie_str_types.decode()

            resp = Response(serializer.data, status=status.HTTP_201_CREATED)
            resp.set_cookie("cart", cookie_str)
            return resp


    def get(self, request):
        """
        查询购物车
        :param request:
        :return:
        """
        try:
            user = request.user
        except:
            user = None

        if user is not None and user.is_authenticated:
            redis_con = get_redis_connection("carts")
            carts_redis = redis_con.hgetall("cart_%s" % user.id)
            selected_redis = redis_con.smembers("selected_%s" % user.id)

            cart_dict = {}
            for sku_id, count in carts_redis.items():
                cart_dict[int(sku_id)] = {
                    "count": count,
                    "seleted": sku_id in selected_redis
                }

        else:
            cookie_str = request.COOKIES.get("cart")
            cookie_str_types = cookie_str.encode()
            cookie_dict_types = base64.b64decode(cookie_str_types)
            cart_dict = pickle.loads(cookie_dict_types)



